home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / EXAMPLES / OLYMPIC.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  9.5 KB  |  413 lines

  1.  
  2. /* Copyright (c) Mark J. Kilgard, 1994. */
  3.  
  4. /**
  5.  * (c) Copyright 1993, 1994, Silicon Graphics, Inc.
  6.  * ALL RIGHTS RESERVED 
  7.  * Permission to use, copy, modify, and distribute this software for 
  8.  * any purpose and without fee is hereby granted, provided that the above
  9.  * copyright notice appear in all copies and that both the copyright notice
  10.  * and this permission notice appear in supporting documentation, and that 
  11.  * the name of Silicon Graphics, Inc. not be used in advertising
  12.  * or publicity pertaining to distribution of the software without specific,
  13.  * written prior permission. 
  14.  *
  15.  * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
  16.  * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
  17.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
  18.  * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
  19.  * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
  20.  * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
  21.  * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
  22.  * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
  23.  * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
  24.  * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
  25.  * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
  26.  * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
  27.  * 
  28.  * US Government Users Restricted Rights 
  29.  * Use, duplication, or disclosure by the Government is subject to
  30.  * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
  31.  * (c)(1)(ii) of the Rights in Technical Data and Computer Software
  32.  * clause at DFARS 252.227-7013 and/or in similar or successor
  33.  * clauses in the FAR or the DOD or NASA FAR Supplement.
  34.  * Unpublished-- rights reserved under the copyright laws of the
  35.  * United States.  Contractor/manufacturer is Silicon Graphics,
  36.  * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
  37.  *
  38.  * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
  39.  */
  40.  
  41. #include <stdio.h>
  42. #include <stdlib.h>
  43. #include <string.h>
  44. #include <math.h>
  45. #include <GL/glut.h>
  46.  
  47. /* Some <math.h> files do not define M_PI... */
  48. #ifndef M_PI
  49. #define M_PI 3.14159265358979323846
  50. #endif
  51.  
  52. #ifdef _WIN32
  53. #define drand48() (((float) rand())/((float) RAND_MAX))
  54. #define srand48(x) (srand((x)))
  55. #else
  56. extern double drand48(void);
  57. extern void srand48(long seedval);
  58. #endif
  59.  
  60. #define XSIZE   100
  61. #define YSIZE   75
  62.  
  63. #define RINGS 5
  64. #define BLUERING 0
  65. #define BLACKRING 1
  66. #define REDRING 2
  67. #define YELLOWRING 3
  68. #define GREENRING 4
  69.  
  70. #define BACKGROUND 8
  71.  
  72. enum {
  73.   BLACK = 0,
  74.   RED,
  75.   GREEN,
  76.   YELLOW,
  77.   BLUE,
  78.   MAGENTA,
  79.   CYAN,
  80.   WHITE
  81. };
  82.  
  83. typedef short Point[2];
  84.  
  85. GLenum rgb, doubleBuffer, directRender;
  86.  
  87. unsigned char rgb_colors[RINGS][3];
  88. int mapped_colors[RINGS];
  89. float dests[RINGS][3];
  90. float offsets[RINGS][3];
  91. float angs[RINGS];
  92. float rotAxis[RINGS][3];
  93. int iters[RINGS];
  94. GLuint theTorus;
  95.  
  96. void
  97. FillTorus(float rc, int numc, float rt, int numt)
  98. {
  99.   int i, j, k;
  100.   double s, t;
  101.   double x, y, z;
  102.   double pi, twopi;
  103.  
  104.   pi = M_PI;
  105.   twopi = 2 * pi;
  106.  
  107.   for (i = 0; i < numc; i++) {
  108.     glBegin(GL_QUAD_STRIP);
  109.     for (j = 0; j <= numt; j++) {
  110.       for (k = 1; k >= 0; k--) {
  111.         s = (i + k) % numc + 0.5;
  112.         t = j % numt;
  113.  
  114.         x = cos(t * twopi / numt) * cos(s * twopi / numc);
  115.         y = sin(t * twopi / numt) * cos(s * twopi / numc);
  116.         z = sin(s * twopi / numc);
  117.         glNormal3f(x, y, z);
  118.  
  119.         x = (rt + rc * cos(s * twopi / numc)) * cos(t * twopi / numt);
  120.         y = (rt + rc * cos(s * twopi / numc)) * sin(t * twopi / numt);
  121.         z = rc * sin(s * twopi / numc);
  122.         glVertex3f(x, y, z);
  123.       }
  124.     }
  125.     glEnd();
  126.   }
  127. }
  128.  
  129. float
  130. Clamp(int iters_left, float t)
  131. {
  132.  
  133.   if (iters_left < 3) {
  134.     return 0.0;
  135.   }
  136.   return (iters_left - 2) * t / iters_left;
  137. }
  138.  
  139. void
  140. Idle(void)
  141. {
  142.   int i, j;
  143.   int more = GL_FALSE;
  144.  
  145.   for (i = 0; i < RINGS; i++) {
  146.     if (iters[i]) {
  147.       for (j = 0; j < 3; j++) {
  148.         offsets[i][j] = Clamp(iters[i], offsets[i][j]);
  149.       }
  150.       angs[i] = Clamp(iters[i], angs[i]);
  151.       iters[i]--;
  152.       more = GL_TRUE;
  153.     }
  154.   }
  155.   if (more) {
  156.     glutPostRedisplay();
  157.   } else {
  158.     glutIdleFunc(NULL);
  159.   }
  160. }
  161.  
  162. void
  163. DrawScene(void)
  164. {
  165.   int i;
  166.  
  167.   glPushMatrix();
  168.  
  169.   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  170.   gluLookAt(0, 0, 10, 0, 0, 0, 0, 1, 0);
  171.  
  172.   for (i = 0; i < RINGS; i++) {
  173.     if (rgb) {
  174.       glColor3ubv(rgb_colors[i]);
  175.     } else {
  176.       glIndexi(mapped_colors[i]);
  177.     }
  178.     glPushMatrix();
  179.     glTranslatef(dests[i][0] + offsets[i][0], dests[i][1] + offsets[i][1],
  180.       dests[i][2] + offsets[i][2]);
  181.     glRotatef(angs[i], rotAxis[i][0], rotAxis[i][1], rotAxis[i][2]);
  182.     glCallList(theTorus);
  183.     glPopMatrix();
  184.   }
  185.  
  186.   glPopMatrix();
  187.   if (doubleBuffer) {
  188.     glutSwapBuffers();
  189.   } else {
  190.     glFlush();
  191.   }
  192. }
  193.  
  194. float
  195. MyRand(void)
  196. {
  197.   return 10.0 * (drand48() - 0.5);
  198. }
  199.  
  200. void
  201. ReInit(void)
  202. {
  203.   int i;
  204.   float deviation;
  205.  
  206.   deviation = MyRand() / 2;
  207.   deviation = deviation * deviation;
  208.   for (i = 0; i < RINGS; i++) {
  209.     offsets[i][0] = MyRand();
  210.     offsets[i][1] = MyRand();
  211.     offsets[i][2] = MyRand();
  212.     angs[i] = 260.0 * MyRand();
  213.     rotAxis[i][0] = MyRand();
  214.     rotAxis[i][1] = MyRand();
  215.     rotAxis[i][2] = MyRand();
  216.     iters[i] = (deviation * MyRand() + 60.0);
  217.   }
  218. }
  219.  
  220. void
  221. Init(void)
  222. {
  223.   int i;
  224.   float top_y = 1.0;
  225.   float bottom_y = 0.0;
  226.   float top_z = 0.15;
  227.   float bottom_z = 0.69;
  228.   float spacing = 2.5;
  229.   static float lmodel_ambient[] =
  230.   {0.0, 0.0, 0.0, 0.0};
  231.   static float lmodel_twoside[] =
  232.   {GL_FALSE};
  233.   static float lmodel_local[] =
  234.   {GL_FALSE};
  235.   static float light0_ambient[] =
  236.   {0.1, 0.1, 0.1, 1.0};
  237.   static float light0_diffuse[] =
  238.   {1.0, 1.0, 1.0, 0.0};
  239.   static float light0_position[] =
  240.   {0.8660254, 0.5, 1, 0};
  241.   static float light0_specular[] =
  242.   {1.0, 1.0, 1.0, 0.0};
  243.   static float bevel_mat_ambient[] =
  244.   {0.0, 0.0, 0.0, 1.0};
  245.   static float bevel_mat_shininess[] =
  246.   {40.0};
  247.   static float bevel_mat_specular[] =
  248.   {1.0, 1.0, 1.0, 0.0};
  249.   static float bevel_mat_diffuse[] =
  250.   {1.0, 0.0, 0.0, 0.0};
  251.  
  252.   srand48(0x102342);
  253.   ReInit();
  254.   for (i = 0; i < RINGS; i++) {
  255.     rgb_colors[i][0] = rgb_colors[i][1] = rgb_colors[i][2] = 0;
  256.   }
  257.   rgb_colors[BLUERING][2] = 255;
  258.   rgb_colors[REDRING][0] = 255;
  259.   rgb_colors[GREENRING][1] = 255;
  260.   rgb_colors[YELLOWRING][0] = 255;
  261.   rgb_colors[YELLOWRING][1] = 255;
  262.   mapped_colors[BLUERING] = BLUE;
  263.   mapped_colors[REDRING] = RED;
  264.   mapped_colors[GREENRING] = GREEN;
  265.   mapped_colors[YELLOWRING] = YELLOW;
  266.   mapped_colors[BLACKRING] = BLACK;
  267.  
  268.   dests[BLUERING][0] = -spacing;
  269.   dests[BLUERING][1] = top_y;
  270.   dests[BLUERING][2] = top_z;
  271.  
  272.   dests[BLACKRING][0] = 0.0;
  273.   dests[BLACKRING][1] = top_y;
  274.   dests[BLACKRING][2] = top_z;
  275.  
  276.   dests[REDRING][0] = spacing;
  277.   dests[REDRING][1] = top_y;
  278.   dests[REDRING][2] = top_z;
  279.  
  280.   dests[YELLOWRING][0] = -spacing / 2.0;
  281.   dests[YELLOWRING][1] = bottom_y;
  282.   dests[YELLOWRING][2] = bottom_z;
  283.  
  284.   dests[GREENRING][0] = spacing / 2.0;
  285.   dests[GREENRING][1] = bottom_y;
  286.   dests[GREENRING][2] = bottom_z;
  287.  
  288.   theTorus = glGenLists(1);
  289.   glNewList(theTorus, GL_COMPILE);
  290.   FillTorus(0.1, 8, 1.0, 25);
  291.   glEndList();
  292.  
  293.   glEnable(GL_CULL_FACE);
  294.   glCullFace(GL_BACK);
  295.   glEnable(GL_DEPTH_TEST);
  296.   glClearDepth(1.0);
  297.  
  298.   if (rgb) {
  299.     glClearColor(0.5, 0.5, 0.5, 0.0);
  300.     glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambient);
  301.     glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
  302.     glLightfv(GL_LIGHT0, GL_SPECULAR, light0_specular);
  303.     glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
  304.     glEnable(GL_LIGHT0);
  305.  
  306.     glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, lmodel_local);
  307.     glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
  308.     glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
  309.     glEnable(GL_LIGHTING);
  310.  
  311.     glMaterialfv(GL_FRONT, GL_AMBIENT, bevel_mat_ambient);
  312.     glMaterialfv(GL_FRONT, GL_SHININESS, bevel_mat_shininess);
  313.     glMaterialfv(GL_FRONT, GL_SPECULAR, bevel_mat_specular);
  314.     glMaterialfv(GL_FRONT, GL_DIFFUSE, bevel_mat_diffuse);
  315.  
  316.     glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
  317.     glEnable(GL_COLOR_MATERIAL);
  318.     glShadeModel(GL_SMOOTH);
  319.   } else {
  320.     glClearIndex(BACKGROUND);
  321.     glShadeModel(GL_FLAT);
  322.   }
  323.  
  324.   glMatrixMode(GL_PROJECTION);
  325.   gluPerspective(45, 1.33, 0.1, 100.0);
  326.   glMatrixMode(GL_MODELVIEW);
  327. }
  328.  
  329. void
  330. Reshape(int width, int height)
  331. {
  332.   glViewport(0, 0, width, height);
  333. }
  334.  
  335. /* ARGSUSED1 */
  336. void
  337. Key(unsigned char key, int x, int y)
  338. {
  339.  
  340.   switch (key) {
  341.   case 27:
  342.     exit(0);
  343.     break;
  344.   case ' ':
  345.     ReInit();
  346.     glutIdleFunc(Idle);
  347.     break;
  348.   }
  349. }
  350.  
  351. GLenum
  352. Args(int argc, char **argv)
  353. {
  354.   GLint i;
  355.  
  356.   rgb = GL_TRUE;
  357.   doubleBuffer = GL_TRUE;
  358.  
  359.   for (i = 1; i < argc; i++) {
  360.     if (strcmp(argv[i], "-ci") == 0) {
  361.       rgb = GL_FALSE;
  362.     } else if (strcmp(argv[i], "-rgb") == 0) {
  363.       rgb = GL_TRUE;
  364.     } else if (strcmp(argv[i], "-sb") == 0) {
  365.       doubleBuffer = GL_FALSE;
  366.     } else if (strcmp(argv[i], "-db") == 0) {
  367.       doubleBuffer = GL_TRUE;
  368.     } else {
  369.       printf("%s (Bad option).\n", argv[i]);
  370.       return GL_FALSE;
  371.     }
  372.   }
  373.   return GL_TRUE;
  374. }
  375.  
  376. void
  377. visible(int vis)
  378. {
  379.   if (vis == GLUT_VISIBLE) {
  380.     glutIdleFunc(Idle);
  381.   } else {
  382.     glutIdleFunc(NULL);
  383.   }
  384. }
  385.  
  386. int
  387. main(int argc, char **argv)
  388. {
  389.   GLenum type;
  390.  
  391.   glutInitWindowSize(400, 300);
  392.   glutInit(&argc, argv);
  393.   if (Args(argc, argv) == GL_FALSE) {
  394.     exit(1);
  395.   }
  396.   type = (rgb) ? GLUT_RGB : GLUT_INDEX;
  397.   type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
  398.   glutInitDisplayMode(type);
  399.  
  400.   glutCreateWindow("Olympic");
  401.  
  402.   Init();
  403.  
  404.   glutReshapeFunc(Reshape);
  405.   glutKeyboardFunc(Key);
  406.   glutDisplayFunc(DrawScene);
  407.  
  408.   glutVisibilityFunc(visible);
  409.  
  410.   glutMainLoop();
  411.   return 0;             /* ANSI C requires main to return int. */
  412. }
  413.